'use client';

import type { TBody, TMetadata } from '@/types';
import Image from 'next/image';
import Link from 'next/link';
import useUser from '@/hooks/useUser';
import LoadPage from '@/app/[locale]/load/load';
import ErrorPage from '@/app/[locale]/error/error';
import { useMutation, useQuery } from '@tanstack/react-query';
import { checkOauthClient, queryOauthClientByClientId } from '@/services/api';
import type {
  ICheckOauthClient,
  ICheckOauthClientBody,
  IOauthClient,
} from '@/interfaces';
import useToast from '@/hooks/useToast';
import { URLPattern } from 'next/server';
import { NavbarPage } from '@/app/[locale]/navbar';
import FooterPage from '@/app/[locale]/footer';
import { useTranslations } from 'use-intl';

export default function OauthAuthPage({ metadata }: { metadata: TMetadata }) {
  return (
    <>
      <NavbarPage metadata={metadata} />
      <OauthAuth metadata={metadata} />
      <FooterPage metadata={metadata} />
    </>
  );
}

const OauthAuth = ({ metadata }: { metadata: TMetadata }) => {
  const t = useTranslations('OauthPage');
  const env = metadata.env;
  const userQuery = useUser(metadata);
  const { show } = useToast();

  const queryOauthClientByClientIdQuery = useQuery(
    metadata.all['client'].k,
    async (context) => {
      return (await queryOauthClientByClientId({
        id: context.queryKey[2] + '',
      })) as IOauthClient;
    },
    {
      initialData: metadata.all['client'].v as IOauthClient,
    },
  );

  const checkOauthClientMutation = useMutation(
    async (variables: TBody<ICheckOauthClientBody>) => {
      return (await checkOauthClient(variables)) as ICheckOauthClient;
    },
  );

  async function onClickAgreeAuthorize() {
    try {
      const params = metadata.all['params'];
      if (!params) {
        show({
          type: 'DANGER',
          message: t('accessDataNotExist'),
        });
        return;
      }

      const paramData = params.v as any;
      if (
        !paramData.responseType ||
        !paramData.clientId ||
        !paramData.redirectUri ||
        !paramData.scope
      ) {
        show({
          type: 'DANGER',
          message: t('accessDataNotExist'),
        });
        return;
      }

      const data = await checkOauthClientMutation.mutateAsync({
        data: paramData,
      });

      if (paramData.state && paramData.state !== data.state) {
        show({
          type: 'DANGER',
          message: t('unidentifiedAuthServer'),
        });

        setTimeout(() => {
          show({
            type: 'DANGER',
            message: t('accessTerminated'),
          });
        }, 2000);

        setTimeout(() => {
          location.href = '/';
        }, 3000);
        return;
      }

      show({
        type: 'SUCCESS',
        message: t('agreeAccessComplete'),
      });

      setTimeout(() => {
        show({
          type: 'PRIMARY',
          message: t('redirecting'),
        });
      }, 1000);

      setTimeout(() => {
        if (data.code && paramData.redirectUri) {
          let href = `${paramData.redirectUri}?code=${data.code}&state=${
            data.state || ''
          }`;

          if (paramData.redirectUri.includes('/yw')) {
            href += `&clientId=${paramData.clientId}`;
          }

          location.href = href;
        } else if (paramData.redirectUri) {
          const urlPattern = new URLPattern(paramData.redirectUri);
          location.href = `${urlPattern.protocol}://${urlPattern.hostname}`;
        } else {
          show({
            type: 'DANGER',
            message: t('failToRedirect'),
          });

          setTimeout(() => {
            show({
              type: 'INFO',
              message: t('tryManuallyReturn'),
            });
          }, 1500);
        }
      }, 1500);
    } catch (e) {
      checkOauthClientMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    }
  }

  function onClickCancelAuthorization() {
    const params = metadata.all['params'];
    if (params) {
      const paramData = params.v as any;
      if (
        paramData.responseType &&
        paramData.clientId &&
        paramData.redirectUri &&
        paramData.scope
      ) {
        show({
          type: 'SUCCESS',
          message: t('accessCancelled'),
        });

        setTimeout(() => {
          show({
            type: 'INFO',
            message: t('toCancelAccessGoToMyPage'),
          });
        }, 1000);

        setTimeout(() => {
          const urlPattern = new URLPattern(paramData.redirectUri);
          location.href = `${urlPattern.protocol}://${urlPattern.hostname}`;
        }, 2000);
        return;
      }
    }

    show({
      type: 'SUCCESS',
      message: t('accessCancelled'),
    });

    setTimeout(() => {
      show({
        type: 'INFO',
        message: t('toCancelAccessGoToMyPage'),
      });
    }, 1500);
  }

  if (
    userQuery.data &&
    userQuery.data.user &&
    queryOauthClientByClientIdQuery.data
  ) {
    const data = queryOauthClientByClientIdQuery.data;
    return (
      <div className="container-fluid p-2 vh-100">
        <div className="text-center h3 py-5">{t('openAuthInProgress')}</div>
        <div
          className="row py-5 justify-content-center gap-5 mx-1"
          style={{ background: 'var(--bs-body-bg)' }}
        >
          <div className="col-12 col-md-5 col-lg-3">
            <div className="vstack gap-4">
              <div className="hstack gap-4 align-items-center">
                <div>
                  <Link href={data.website || '#'}>
                    {data.logo ? (
                      <Image
                        className="object-fit-cover rounded-circle"
                        src={data.logo}
                        alt={data.name}
                        title={data.name}
                        width={48}
                        height={48}
                        placeholder="blur"
                        blurDataURL={env.APP_BLUR_DATA_URL}
                      />
                    ) : (
                      <div
                        title={`${data.name} ${t('noAppIconSet')}`}
                        className="rounded-circle bg-light"
                        style={{ width: 48, height: 48 }}
                      />
                    )}
                  </Link>
                </div>
                <div className="fw-medium" title={data.overview || data.name}>
                  <Link
                    className="text-decoration-none text-decoration-underline-hover link-dark fw-medium"
                    href={data.website || '#'}
                  >
                    {data.name}
                  </Link>
                </div>
              </div>
              <div>
                <i className="bi bi-info-circle me-2"></i>
                {t('authorizingAppNameLogin', { name: data.name })}
              </div>
              <div className="text-secondary">
                <ul className="vstack gap-2">
                  <li className="hstack align-items-center gap-2">
                    <div>{t('linkYourAccount')}</div>
                    <input
                      className="form-check-input mt-0"
                      type="checkbox"
                      value=""
                      checked
                      disabled
                    />
                  </li>
                  <li className="hstack align-items-center gap-2">
                    <div>{t('accessAliasSignAvatar')}</div>
                    <input
                      className="form-check-input mt-0"
                      type="checkbox"
                      value=""
                      checked
                      disabled
                    />
                  </li>
                </ul>
              </div>
              <div className="text-secondary">
                {t('dataManagedByPrivacyPolicy', { name: data.name })}
                <Link
                  className="text-decoration-none text-decoration-underline-hover"
                  href={`/users/${userQuery.data.user.id}`}
                >
                  {t('myPage')}
                </Link>
                {t('cancelAppAccess')}
              </div>
            </div>
          </div>
          <div className="d-none d-md-block col-md-auto">
            <div className="vr h-100 text-muted"></div>
          </div>
          <div className="col-12 col-md-5 col-lg-3 align-self-center">
            <div className="d-grid gap-4">
              <button
                disabled={
                  checkOauthClientMutation.isLoading ||
                  checkOauthClientMutation.isSuccess
                }
                onClick={onClickAgreeAuthorize}
                className="btn btn-primary"
                type="button"
              >
                {checkOauthClientMutation.isLoading ? (
                  <span
                    className="spinner-border spinner-border-sm me-2"
                    role="status"
                    aria-hidden="true"
                  ></span>
                ) : (
                  <i className="bi bi-check-lg me-2"></i>
                )}
                {t('agreeAccess')}
              </button>
              <button
                disabled={
                  checkOauthClientMutation.isLoading ||
                  checkOauthClientMutation.isSuccess
                }
                onClick={onClickCancelAuthorization}
                className="btn btn-light"
                type="button"
              >
                <i className="bi bi-x-lg me-2"></i>
                {t('cancelAccess')}
              </button>
            </div>
          </div>
        </div>
        <div style={{ paddingBottom: '2rem', paddingTop: '2rem' }}></div>
      </div>
    );
  }

  if (userQuery.error || queryOauthClientByClientIdQuery.error) {
    return (
      <ErrorPage
        error={userQuery.error || queryOauthClientByClientIdQuery.error}
      />
    );
  }

  return <LoadPage />;
};
